#include "uart.h"

// https://developer.arm.com/documentation/dui0159/b/peripherals-and-interfaces/uart-interface/overview-of-uart-registers
// https://developer.arm.com/documentation/ddi0183/f/programmer-s-model/summary-of-registers

struct uart_regs
{
    unsigned UARTDR;
    unsigned UARTRSR;
    unsigned _res_8;
    unsigned _res_c;
    unsigned _res_10;
    unsigned _res_14;
    unsigned UARTFR;
    unsigned _res_1c;
    unsigned UARTILPR;
    unsigned UARTIBRD;
    unsigned UARTFBRD;
    unsigned UARTLCR_H;
    unsigned UARTCR;
};

#define UART0 (*(volatile struct uart_regs *)0x16000000)

void uart_init(void)
{
    UART0.UARTIBRD = 1;
    UART0.UARTFBRD = 0;
    UART0.UARTLCR_H = 0b01100000; // WLEN = 11 (word length = 8 bits)
    UART0.UARTCR = 0b0000000100000001; // UARTEN = 1 (UART enable), TXE = 1 (transmit enable)
}

void uart_putchar(char c)
{
    UART0.UARTDR = c;
    while (!(UART0.UARTFR & 0b010000000)); // TXFE = 1 (transmit register empty)
}
